﻿// The AccessHelper class is intended to encapsulate high performance, scalable best practices for 
// common uses of OleDBClient.

// ===============================================================================
// Release history
// VERSION	DESCRIPTION
//   2.0	Added support for FillDataset, UpdateDataset and "Param" helper methods
//   2.1 Added ExecuteScalarWithIdentity methods to return Identity after adding a new record
//
// ===============================================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Data.OleDb;


namespace Vit.Database.Helpers
{
    public sealed class AccessHelper
    {
        #region "private utility methods & constructors"

        // Since this class provides only static methods, make the default constructor private to prevent 
        // instances from being created with "new AccessHelper()".
        private AccessHelper()
        {
        }
        // New

        // This method is used to attach array of OleDBParameters to a OleDBCommand.
        // This method will assign a value of DbNull to any parameter with a direction of
        // InputOutput and a value of null.  
        // This behavior will prevent default values from being used, but
        // this will be the less common case than an intended pure output parameter (derived as InputOutput)
        // where the user provided no input value.
        // Parameters:
        // -command - The command to which the parameters will be added
        // -commandParameters - an array of OleDBParameters to be added to command
        private static void AttachParameters(OleDbCommand command, OleDbParameter[] commandParameters)
        {
            if ((command == null))
                throw new ArgumentNullException("command");
            if (((commandParameters != null)))
            {
                OleDbParameter p = null;
                foreach (OleDbParameter p_loopVariable in commandParameters)
                {
                    p = p_loopVariable;
                    if (((p != null)))
                    {
                        // Check for derived output value with no value assigned
                        if ((p.Direction == ParameterDirection.InputOutput || p.Direction == ParameterDirection.Input) && p.Value == null)
                        {
                            p.Value = DBNull.Value;
                        }
                        command.Parameters.Add(p);
                    }
                }
            }
        }
        // AttachParameters

        // This method assigns dataRow column values to an array of OleDBParameters.
        // Parameters:
        // -commandParameters: Array of OleDBParameters to be assigned values
        // -dataRow: the dataRow used to hold the stored procedure' s parameter values

        private static void AssignParameterValues(OleDbParameter[] commandParameters, DataRow dataRow)
        {
            if (commandParameters == null || dataRow == null)
            {
                // Do nothing if we get no data    
                return;
            }

            // Set the parameters values
            OleDbParameter commandParameter = null;
            int i = 0;
            foreach (OleDbParameter commandParameter_loopVariable in commandParameters)
            {
                commandParameter = commandParameter_loopVariable;
                // Check the parameter name
                if ((commandParameter.ParameterName == null || commandParameter.ParameterName.Length <= 1))
                {
                    throw new Exception(string.Format("Please provide a valid parameter name on the parameter #{0}, the ParameterName property has the following value: ' {1}' .", i, commandParameter.ParameterName));
                }
                if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1)
                {
                    commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)];
                }
                i = i + 1;
            }
        }

        // This method assigns an array of values to an array of OleDBParameters.
        // Parameters:
        // -commandParameters - array of OleDBParameters to be assigned values
        // -array of objects holding the values to be assigned

        private static void AssignParameterValues(OleDbParameter[] commandParameters, object[] parameterValues)
        {
            int i = 0;
            int j = 0;

            if ((commandParameters == null) && (parameterValues == null))
            {
                // Do nothing if we get no data
                return;
            }

            // We must have the same number of values as we pave parameters to put them in
            if (commandParameters.Length != parameterValues.Length)
            {
                throw new ArgumentException("Parameter count does not match Parameter Value count.");
            }

            // Value array
            j = commandParameters.Length - 1;
            for (i = 0; i <= j; i++)
            {
                // If the current array value derives from IDbDataParameter, then assign its Value property
                if (parameterValues[i] is IDbDataParameter)
                {
                    IDbDataParameter paramInstance = (IDbDataParameter)parameterValues[i];
                    if ((paramInstance.Value == null))
                    {
                        commandParameters[i].Value = DBNull.Value;
                    }
                    else
                    {
                        commandParameters[i].Value = paramInstance.Value;
                    }
                }
                else if ((parameterValues[i] == null))
                {
                    commandParameters[i].Value = DBNull.Value;
                }
                else
                {
                    commandParameters[i].Value = parameterValues[i];
                }
            }
        }
        // AssignParameterValues

        // This method opens (if necessary) and assigns a connection, transaction, command type and parameters 
        // to the provided command.
        // Parameters:
        // -command - the OleDBCommand to be prepared
        // -connection - a valid OleDBConnection, on which to execute this command
        // -transaction - a valid OleDBTransaction, or ' null' 
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // -commandParameters - an array of OleDBParameters to be associated with the command or ' null' if no parameters are required

        private static void PrepareCommand(OleDbCommand command, OleDbConnection connection, OleDbTransaction transaction, CommandType commandType, string commandText, OleDbParameter[] commandParameters, ref bool mustCloseConnection)
        {
            if ((command == null))
                throw new ArgumentNullException("command");
            if ((commandText == null || commandText.Length == 0))
                throw new ArgumentNullException("commandText");

            // If the provided connection is not open, we will open it
            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
                mustCloseConnection = true;
            }
            else
            {
                mustCloseConnection = false;
            }

            // Associate the connection with the command
            command.Connection = connection;

            // Set the command text (stored procedure name or OleDB statement)
            command.CommandText = commandText;

            // If we were provided a transaction, assign it.
            if ((transaction != null))
            {
                if (transaction.Connection == null)
                    throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
                command.Transaction = transaction;
            }

            // Set the command type
            command.CommandType = commandType;

            // Attach the command parameters if they are provided
            if ((commandParameters != null))
            {
                AttachParameters(command, commandParameters);
            }
            return;
        }
        // PrepareCommand

        #endregion

        #region "ExecuteNonQuery"

        // Execute a OleDBCommand (that returns no resultset and takes no parameters) against the database specified in 
        // the connection string. 
        // e.g.:  
        //  Dim result As Integer =  ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders")
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // Returns: An int representing the number of rows affected by the command
        public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteNonQuery(connectionString, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteNonQuery

        // Execute a OleDBCommand (that returns no resultset) against the database specified in the connection string 
        // using the provided parameters.
        // e.g.:  
        // Dim result As Integer = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // -commandParameters - an array of OleDBParamters used to execute the command
        // Returns: An int representing the number of rows affected by the command
        public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");
            // Create & open a OleDBConnection, and dispose of it after we are done
            OleDbConnection connection = null;
            try
            {
                connection = new OleDbConnection(connectionString);
                connection.Open();

                // Call the overload that takes a connection in place of the connection string
                return ExecuteNonQuery(connection, commandType, commandText, commandParameters);
            }
            finally
            {
                if ((connection != null))
                    connection.Dispose();
            }
        }
        // ExecuteNonQuery

        // Execute a OleDBCommand (that returns no resultset and takes no parameters) against the provided OleDBConnection. 
        // e.g.:  
        // Dim result As Integer = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders")
        // Parameters:
        // -connection - a valid OleDBConnection
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command 
        // Returns: An int representing the number of rows affected by the command
        public static int ExecuteNonQuery(OleDbConnection connection, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteNonQuery(connection, commandType, commandText, (OleDbParameter[])null);

        }
        // ExecuteNonQuery

        // Execute a OleDBCommand (that returns no resultset) against the specified OleDBConnection 
        // using the provided parameters.
        // e.g.:  
        //  Dim result As Integer = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connection - a valid OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: An int representing the number of rows affected by the command 
        public static int ExecuteNonQuery(OleDbConnection connection, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {

            if ((connection == null))
                throw new ArgumentNullException("connection");

            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            int retval = 0;
            bool mustCloseConnection = false;

            PrepareCommand(cmd, connection, (OleDbTransaction)null, commandType, commandText, commandParameters, ref mustCloseConnection);

            // Finally, execute the command
            retval = cmd.ExecuteNonQuery();

            if ((mustCloseConnection))
                connection.Close();

            return retval;
        }
        // ExecuteNonQuery

        // Execute a OleDBCommand (that returns no resultset and takes no parameters) against the provided OleDBTransaction.
        // e.g.:  
        //  Dim result As Integer = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders")
        // Parameters:
        // -transaction - a valid OleDBTransaction associated with the connection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // Returns: An int representing the number of rows affected by the command 
        public static int ExecuteNonQuery(OleDbTransaction transaction, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteNonQuery(transaction, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteNonQuery

        // Execute a OleDBCommand (that returns no resultset) against the specified OleDBTransaction
        // using the provided parameters.
        // e.g.:  
        // Dim result As Integer = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -transaction - a valid OleDBTransaction 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: An int representing the number of rows affected by the command 
        public static int ExecuteNonQuery(OleDbTransaction transaction, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {

            if ((transaction == null))
                throw new ArgumentNullException("transaction");
            if ((transaction != null) && (transaction.Connection == null))
                throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            int retval = 0;
            bool mustCloseConnection = false;

            PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, ref mustCloseConnection);

            // Finally, execute the command
            retval = cmd.ExecuteNonQuery();

            return retval;
        }
        // ExecuteNonQuery

        #endregion

        #region "ExecuteDataset"

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the database specified in 
        // the connection string. 
        // e.g.:  
        // Dim ds As DataSet = AccessHelper.ExecuteDataset("", commandType.StoredProcedure, "GetOrders")
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // Returns: A dataset containing the resultset generated by the command
        public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteDataset(connectionString, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteDataset

        // Execute a OleDBCommand (that returns a resultset) against the database specified in the connection string 
        // using the provided parameters.
        // e.g.:  
        // Dim ds As Dataset = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // -commandParameters - an array of OleDBParamters used to execute the command
        // Returns: A dataset containing the resultset generated by the command
        public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {

            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");

            // Create & open a OleDBConnection, and dispose of it after we are done
            OleDbConnection connection = null;
            try
            {
                connection = new OleDbConnection(connectionString);
                connection.Open();

                // Call the overload that takes a connection in place of the connection string
                return ExecuteDataset(connection, commandType, commandText, commandParameters);
            }
            finally
            {
                if ((connection != null))
                    connection.Dispose();
            }
        }
        // ExecuteDataset

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the provided OleDBConnection. 
        // e.g.:  
        // Dim ds As Dataset = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders")
        // Parameters:
        // -connection - a valid OleDBConnection
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // Returns: A dataset containing the resultset generated by the command
        public static DataSet ExecuteDataset(OleDbConnection connection, CommandType commandType, string commandText)
        {

            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteDataset(connection, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteDataset

        // Execute a OleDBCommand (that returns a resultset) against the specified OleDBConnection 
        // using the provided parameters.
        // e.g.:  
        // Dim ds As Dataset = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connection - a valid OleDBConnection
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // -commandParameters - an array of OleDBParamters used to execute the command
        // Returns: A dataset containing the resultset generated by the command
        public static DataSet ExecuteDataset(OleDbConnection connection, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((connection == null))
                throw new ArgumentNullException("connection");
            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            DataSet ds = new DataSet();
            OleDbDataAdapter dataAdatpter = null;
            bool mustCloseConnection = false;

            PrepareCommand(cmd, connection, (OleDbTransaction)null, commandType, commandText, commandParameters, ref mustCloseConnection);

            try
            {
                // Create the DataAdapter & DataSet
                dataAdatpter = new OleDbDataAdapter(cmd);

                // Fill the DataSet using default values for DataTable names, etc
                dataAdatpter.Fill(ds);
            }
            finally
            {
                if (((dataAdatpter != null)))
                    dataAdatpter.Dispose();
            }
            if ((mustCloseConnection))
                connection.Close();

            // Return the dataset
            return ds;
        }
        // ExecuteDataset

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the provided OleDBTransaction. 
        // e.g.:  
        // Dim ds As Dataset = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders")
        // Parameters
        // -transaction - a valid OleDBTransaction
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // Returns: A dataset containing the resultset generated by the command
        public static DataSet ExecuteDataset(OleDbTransaction transaction, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteDataset(transaction, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteDataset

        // Execute a OleDBCommand (that returns a resultset) against the specified OleDBTransaction
        // using the provided parameters.
        // e.g.:  
        // Dim ds As Dataset = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new OleDBParameter("@prodid", 24))
        // Parameters
        // -transaction - a valid OleDBTransaction 
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or T-OleDB command
        // -commandParameters - an array of OleDBParamters used to execute the command
        // Returns: A dataset containing the resultset generated by the command
        public static DataSet ExecuteDataset(OleDbTransaction transaction, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((transaction == null))
                throw new ArgumentNullException("transaction");
            if ((transaction != null) && (transaction.Connection == null))
                throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            DataSet ds = new DataSet();
            OleDbDataAdapter dataAdatpter = null;
            bool mustCloseConnection = false;

            PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, ref mustCloseConnection);

            try
            {
                // Create the DataAdapter & DataSet
                dataAdatpter = new OleDbDataAdapter(cmd);

                // Fill the DataSet using default values for DataTable names, etc
                dataAdatpter.Fill(ds);
            }
            finally
            {
                if (((dataAdatpter != null)))
                    dataAdatpter.Dispose();
            }

            // Return the dataset
            return ds;

        }
        // ExecuteDataset

        #endregion

        #region "ExecuteReader"
        // this enum is used to indicate whether the connection was provided by the caller, or created by AccessHelper, so that
        // we can set the appropriate CommandBehavior when calling ExecuteReader()
        private enum OleDBConnectionOwnership
        {
            // Connection is owned and managed by AccessHelper
            Internal,
            // Connection is owned and managed by the caller
            External
        }
        // OleDBConnectionOwnership

        // Create and prepare a OleDBCommand, and call ExecuteReader with the appropriate CommandBehavior.
        // If we created and opened the connection, we want the connection to be closed when the DataReader is closed.
        // If the caller provided the connection, we want to leave it to them to manage.
        // Parameters:
        // -connection - a valid OleDBConnection, on which to execute this command 
        // -transaction - a valid OleDBTransaction, or ' null' 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or SQL command 
        // -commandParameters - an array of OleDBParameters to be associated with the command or ' null' if no parameters are required 
        // -connectionOwnership - indicates whether the connection parameter was provided by the caller, or created by AccessHelper 
        // Returns: OleDBDataReader containing the results of the command 
        private static OleDbDataReader ExecuteReader(OleDbConnection connection, OleDbTransaction transaction, CommandType commandType, string commandText, OleDbParameter[] commandParameters, OleDBConnectionOwnership connectionOwnership)
        {

            if ((connection == null))
                throw new ArgumentNullException("connection");

            bool mustCloseConnection = false;
            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            try
            {
                // Create a reader
                OleDbDataReader dataReader = null;

                PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, ref mustCloseConnection);

                // Call ExecuteReader with the appropriate CommandBehavior
                if (connectionOwnership == OleDBConnectionOwnership.External)
                {
                    dataReader = cmd.ExecuteReader();
                }
                else
                {
                    dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                }

                return dataReader;
            }
            catch
            {
                if ((mustCloseConnection))
                    connection.Close();
                throw;
            }
        }
        // ExecuteReader

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the database specified in 
        // the connection string. 
        // e.g.:  
        // Dim dr As OleDBDataReader = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders")
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or SQL command 
        // Returns: A OleDBDataReader containing the resultset generated by the command 
        public static OleDbDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteReader(connectionString, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteReader

        // Execute a OleDBCommand (that returns a resultset) against the database specified in the connection string 
        // using the provided parameters.
        // e.g.:  
        // Dim dr As OleDBDataReader = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or SQL command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: A OleDBDataReader containing the resultset generated by the command 
        public static OleDbDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");

            // Create & open a OleDBConnection
            OleDbConnection connection = null;
            try
            {
                connection = new OleDbConnection(connectionString);
                connection.Open();
                // Call the private overload that takes an internally owned connection in place of the connection string
                return ExecuteReader(connection, (OleDbTransaction)null, commandType, commandText, commandParameters, OleDBConnectionOwnership.Internal);
            }
            catch
            {
                // If we fail to return the OleDBDatReader, we need to close the connection ourselves
                if ((connection != null))
                    connection.Dispose();
                throw;
            }
        }
        // ExecuteReader

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the provided OleDBConnection. 
        // e.g.:  
        // Dim dr As OleDBDataReader = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders")
        // Parameters:
        // -connection - a valid OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or SQL command 
        // Returns: A OleDBDataReader containing the resultset generated by the command 
        public static OleDbDataReader ExecuteReader(OleDbConnection connection, CommandType commandType, string commandText)
        {

            return ExecuteReader(connection, commandType, commandText, (OleDbParameter[])null);

        }
        // ExecuteReader

        // Execute a OleDBCommand (that returns a resultset) against the specified OleDBConnection 
        // using the provided parameters.
        // e.g.:  
        // Dim dr As OleDBDataReader = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connection - a valid OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or SQL command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: A OleDBDataReader containing the resultset generated by the command 
        public static OleDbDataReader ExecuteReader(OleDbConnection connection, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            // Pass through the call to private overload using a null transaction value
            return ExecuteReader(connection, (OleDbTransaction)null, commandType, commandText, commandParameters, OleDBConnectionOwnership.External);

        }
        // ExecuteReader

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the provided OleDBTransaction.
        // e.g.:  
        // Dim dr As OleDBDataReader = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders")
        // Parameters:
        // -transaction - a valid OleDBTransaction  
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or SQL command 
        // Returns: A OleDBDataReader containing the resultset generated by the command 
        public static OleDbDataReader ExecuteReader(OleDbTransaction transaction, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteReader(transaction, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteReader

        // Execute a OleDBCommand (that returns a resultset) against the specified OleDBTransaction
        // using the provided parameters.
        // e.g.:  
        // Dim dr As OleDBDataReader = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new OleDBParameter("@prodid", 24))
        // Parameters:
        // -transaction - a valid OleDBTransaction 
        // -commandType - the CommandType (stored procedure, text, etc.)
        // -commandText - the stored procedure name or SQL command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: A OleDBDataReader containing the resultset generated by the command 
        public static OleDbDataReader ExecuteReader(OleDbTransaction transaction, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((transaction == null))
                throw new ArgumentNullException("transaction");
            if ((transaction != null) && (transaction.Connection == null))
                throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
            // Pass through to private overload, indicating that the connection is owned by the caller
            return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, OleDBConnectionOwnership.External);
        }
        // ExecuteReader

        #endregion

        #region "ExecuteScalar"

        // Execute a OleDBCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in 
        // the connection string. 
        // e.g.:  
        // Dim orderCount As Integer = CInt(ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount"))
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // Returns: An object containing the value in the 1x1 resultset generated by the command
        public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteScalar(connectionString, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteScalar

        // Execute a OleDBCommand (that returns a 1x1 resultset) against the database specified in the connection string 
        // using the provided parameters.
        // e.g.:  
        // Dim orderCount As Integer = Cint(ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new OleDBParameter("@prodid", 24)))
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: An object containing the value in the 1x1 resultset generated by the command 
        public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");
            // Create & open a OleDBConnection, and dispose of it after we are done.
            OleDbConnection connection = null;
            try
            {
                connection = new OleDbConnection(connectionString);
                connection.Open();

                // Call the overload that takes a connection in place of the connection string
                return ExecuteScalar(connection, commandType, commandText, commandParameters);
            }
            finally
            {
                if ((connection != null))
                    connection.Dispose();
            }
        }
        // ExecuteScalar

        // Execute a OleDBCommand (that returns the @Identity) against the database specified in the connection string 
        // using the provided parameters.
        // e.g.:  
        // Dim orderCount As Integer = Cint(ExecuteScalarWithIdentity(connString, CommandType.StoredProcedure, "AddNewOrder", new OleDBParameter("@orderName", 24)))
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: An integer containing the @identity of the new record
        public static int ExecuteScalarWithIdentity(string connectionString, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");
            // Create & open a OleDBConnection, and dispose of it after we are done.
            OleDbConnection connection = null;
            try
            {
                connection = new OleDbConnection(connectionString);
                connection.Open();

                // Call the overload that takes a connection in place of the connection string
                return ExecuteScalarWithIdentity(connection, commandType, commandText, commandParameters);
            }
            finally
            {
                if ((connection != null))
                    connection.Dispose();
            }
        }
        // ExecuteScalarWithIdentity

        // Execute a OleDBCommand (that returns a 1x1 resultset and takes no parameters) against the provided OleDBConnection. 
        // e.g.:  
        // Dim orderCount As Integer = CInt(ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount"))
        // Parameters:
        // -connection - a valid OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // Returns: An object containing the value in the 1x1 resultset generated by the command 
        public static object ExecuteScalar(OleDbConnection connection, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteScalar(connection, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteScalar

        // Execute a OleDBCommand (that returns a 1x1 resultset) against the specified OleDBConnection 
        // using the provided parameters.
        // e.g.:  
        // Dim orderCount As Integer = CInt(ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new OleDBParameter("@prodid", 24)))
        // Parameters:
        // -connection - a valid OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: An object containing the value in the 1x1 resultset generated by the command 
        public static object ExecuteScalar(OleDbConnection connection, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {

            if ((connection == null))
                throw new ArgumentNullException("connection");

            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            object retval = null;
            bool mustCloseConnection = false;

            PrepareCommand(cmd, connection, (OleDbTransaction)null, commandType, commandText, commandParameters, ref mustCloseConnection);

            // Execute the command & return the results
            retval = cmd.ExecuteScalar();

            if ((mustCloseConnection))
                connection.Close();

            return retval;

        }
        // ExecuteScalar

        // Execute a OleDBCommand (that returns the @Identity) against the specified OleDBConnection 
        // using the provided parameters.
        // e.g.:  
        // Dim orderCount As Integer = Cint(ExecuteScalarWithIdentity(connString, CommandType.StoredProcedure, "AddNewOrder", new OleDBParameter("@orderName", 24)))
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: An integer containing the @identity of the new record
        public static int ExecuteScalarWithIdentity(OleDbConnection connection, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {

            if ((connection == null))
                throw new ArgumentNullException("connection");

            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            OleDbCommand idCmd = new OleDbCommand();
            idCmd.CommandText = "SELECT @@IDENTITY";
            int retval = 0;
            bool mustCloseConnection = false;

            PrepareCommand(cmd, connection, (OleDbTransaction)null, commandType, commandText, commandParameters, ref mustCloseConnection);

            // Execute the command & return the results
            cmd.ExecuteNonQuery();
            idCmd.Connection = connection;
            retval = Convert.ToInt32(idCmd.ExecuteScalar());

            if ((mustCloseConnection))
                connection.Close();

            return retval;

        }
        // ExecuteScalarWithIdentity

        // Execute a OleDBCommand (that returns a 1x1 resultset and takes no parameters) against the provided OleDBTransaction.
        // e.g.:  
        // Dim orderCount As Integer  = CInt(ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount"))
        // Parameters:
        // -transaction - a valid OleDBTransaction 
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // Returns: An object containing the value in the 1x1 resultset generated by the command 
        public static object ExecuteScalar(OleDbTransaction transaction, CommandType commandType, string commandText)
        {
            // Pass through the call providing null for the set of OleDBParameters
            return ExecuteScalar(transaction, commandType, commandText, (OleDbParameter[])null);
        }
        // ExecuteScalar

        // Execute a OleDBCommand (that returns a 1x1 resultset) against the specified OleDBTransaction
        // using the provided parameters.
        // e.g.:  
        // Dim orderCount As Integer = CInt(ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new OleDBParameter("@prodid", 24)))
        // Parameters:
        // -transaction - a valid OleDBTransaction  
        // -commandType - the CommandType (stored procedure, text, etc.) 
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters used to execute the command 
        // Returns: An object containing the value in the 1x1 resultset generated by the command 
        public static object ExecuteScalar(OleDbTransaction transaction, CommandType commandType, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((transaction == null))
                throw new ArgumentNullException("transaction");
            if ((transaction != null) && (transaction.Connection == null))
                throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");

            // Create a command and prepare it for execution
            OleDbCommand cmd = new OleDbCommand();
            object retval = null;
            bool mustCloseConnection = false;

            PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, ref mustCloseConnection);

            // Execute the command & return the results
            retval = cmd.ExecuteScalar();

            return retval;
        }
        // ExecuteScalar

        #endregion

        #region "FillDataset"
        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the database specified in 
        // the connection string. 
        // e.g.:  
        //   FillDataset (connString, CommandType.StoredProcedure, "GetOrders", ds, new String() {"orders"})
        // Parameters:    
        // -connectionString: A valid connection string for a OleDBConnection
        // -commandType: the CommandType (stored procedure, text, etc.)
        // -commandText: the stored procedure name or T-OleDB command
        // -dataSet: A dataset wich will contain the resultset generated by the command
        // -tableNames: this array will be used to create table mappings allowing the DataTables to be referenced
        //               by a user defined name (probably the actual table name)

        public static void FillDataset(string connectionString, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");
            if ((dataSet == null))
                throw new ArgumentNullException("dataSet");

            // Create & open a OleDBConnection, and dispose of it after we are done
            OleDbConnection connection = null;
            try
            {
                connection = new OleDbConnection(connectionString);

                connection.Open();

                // Call the overload that takes a connection in place of the connection string
                FillDataset(connection, commandType, commandText, dataSet, tableNames);
            }
            finally
            {
                if ((connection != null))
                    connection.Dispose();
            }
        }

        // Execute a OleDBCommand (that returns a resultset) against the database specified in the connection string 
        // using the provided parameters.
        // e.g.:  
        //   FillDataset (connString, CommandType.StoredProcedure, "GetOrders", ds, new String() = {"orders"}, new OleDBParameter("@prodid", 24))
        // Parameters:    
        // -connectionString: A valid connection string for a OleDBConnection
        // -commandType: the CommandType (stored procedure, text, etc.)
        // -commandText: the stored procedure name or T-OleDB command
        // -dataSet: A dataset wich will contain the resultset generated by the command
        // -tableNames: this array will be used to create table mappings allowing the DataTables to be referenced
        //               by a user defined name (probably the actual table name)
        // -commandParameters: An array of OleDBParamters used to execute the command

        public static void FillDataset(string connectionString, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames, params OleDbParameter[] commandParameters)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");
            if ((dataSet == null))
                throw new ArgumentNullException("dataSet");

            // Create & open a OleDBConnection, and dispose of it after we are done
            OleDbConnection connection = null;
            try
            {
                connection = new OleDbConnection(connectionString);

                connection.Open();

                // Call the overload that takes a connection in place of the connection string
                FillDataset(connection, commandType, commandText, dataSet, tableNames, commandParameters);
            }
            finally
            {
                if ((connection != null))
                    connection.Dispose();
            }
        }

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the provided OleDBConnection. 
        // e.g.:  
        //   FillDataset (conn, CommandType.StoredProcedure, "GetOrders", ds, new String() {"orders"})
        // Parameters:
        // -connection: A valid OleDBConnection
        // -commandType: the CommandType (stored procedure, text, etc.)
        // -commandText: the stored procedure name or T-OleDB command
        // -dataSet: A dataset wich will contain the resultset generated by the command
        // -tableNames: this array will be used to create table mappings allowing the DataTables to be referenced
        // by a user defined name (probably the actual table name)

        public static void FillDataset(OleDbConnection connection, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)
        {
            FillDataset(connection, commandType, commandText, dataSet, tableNames, null);

        }

        // Execute a OleDBCommand (that returns a resultset) against the specified OleDBConnection 
        // using the provided parameters.
        // e.g.:  
        //   FillDataset (conn, CommandType.StoredProcedure, "GetOrders", ds, new String() {"orders"}, new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connection: A valid OleDBConnection
        // -commandType: the CommandType (stored procedure, text, etc.)
        // -commandText: the stored procedure name or T-OleDB command
        // -dataSet: A dataset wich will contain the resultset generated by the command
        // -tableNames: this array will be used to create table mappings allowing the DataTables to be referenced
        // by a user defined name (probably the actual table name)
        // -commandParameters: An array of OleDBParamters used to execute the command

        public static void FillDataset(OleDbConnection connection, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames, params OleDbParameter[] commandParameters)
        {
            FillDataset(connection, null, commandType, commandText, dataSet, tableNames, commandParameters);

        }

        // Execute a OleDBCommand (that returns a resultset and takes no parameters) against the provided OleDBTransaction. 
        // e.g.:  
        //   FillDataset (trans, CommandType.StoredProcedure, "GetOrders", ds, new string() {"orders"})
        // Parameters:
        // -transaction: A valid OleDBTransaction
        // -commandType: the CommandType (stored procedure, text, etc.)
        // -commandText: the stored procedure name or T-OleDB command
        // -dataSet: A dataset wich will contain the resultset generated by the command
        // -tableNames: this array will be used to create table mappings allowing the DataTables to be referenced
        //             by a user defined name (probably the actual table name)

        public static void FillDataset(OleDbTransaction transaction, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames)
        {
            FillDataset(transaction, commandType, commandText, dataSet, tableNames, null);
        }

        // Execute a OleDBCommand (that returns a resultset) against the specified OleDBTransaction
        // using the provided parameters.
        // e.g.:  
        //   FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string() {"orders"}, new OleDBParameter("@prodid", 24))
        // Parameters:
        // -transaction: A valid OleDBTransaction
        // -commandType: the CommandType (stored procedure, text, etc.)
        // -commandText: the stored procedure name or T-OleDB command
        // -dataSet: A dataset wich will contain the resultset generated by the command
        // -tableNames: this array will be used to create table mappings allowing the DataTables to be referenced
        // by a user defined name (probably the actual table name)
        // -commandParameters: An array of OleDBParamters used to execute the command

        public static void FillDataset(OleDbTransaction transaction, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames, params OleDbParameter[] commandParameters)
        {
            if ((transaction == null))
                throw new ArgumentNullException("transaction");
            if ((transaction != null) && (transaction.Connection == null))
                throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
            FillDataset(transaction.Connection, transaction, commandType, commandText, dataSet, tableNames, commandParameters);

        }

        // Private helper method that execute a OleDBCommand (that returns a resultset) against the specified OleDBTransaction and OleDBConnection
        // using the provided parameters.
        // e.g.:  
        //   FillDataset(conn, trans, CommandType.StoredProcedure, "GetOrders", ds, new String() {"orders"}, new OleDBParameter("@prodid", 24))
        // Parameters:
        // -connection: A valid OleDBConnection
        // -transaction: A valid OleDBTransaction
        // -commandType: the CommandType (stored procedure, text, etc.)
        // -commandText: the stored procedure name or T-OleDB command
        // -dataSet: A dataset wich will contain the resultset generated by the command
        // -tableNames: this array will be used to create table mappings allowing the DataTables to be referenced
        //             by a user defined name (probably the actual table name)
        // -commandParameters: An array of OleDBParamters used to execute the command

        private static void FillDataset(OleDbConnection connection, OleDbTransaction transaction, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames, params OleDbParameter[] commandParameters)
        {
            if ((connection == null))
                throw new ArgumentNullException("connection");
            if ((dataSet == null))
                throw new ArgumentNullException("dataSet");

            // Create a command and prepare it for execution
            OleDbCommand command = new OleDbCommand();

            bool mustCloseConnection = false;
            PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, ref mustCloseConnection);

            // Create the DataAdapter & DataSet
            OleDbDataAdapter dataAdapter = new OleDbDataAdapter(command);

            try
            {
                // Add the table mappings specified by the user

                if ((tableNames != null) && tableNames.Length > 0)
                {
                    string tableName = "Table";
                    int index = 0;

                    for (index = 0; index <= tableNames.Length - 1; index++)
                    {
                        if ((tableNames[index] == null || tableNames[index].Length == 0))
                            throw new ArgumentException("The tableNames parameter must contain a list of tables, a value was provided as null or empty string.", "tableNames");
                        dataAdapter.TableMappings.Add(tableName, tableNames[index]);
                        tableName = tableName + (index + 1).ToString();
                    }
                }

                // Fill the DataSet using default values for DataTable names, etc
                dataAdapter.Fill(dataSet);

            }
            finally
            {
                if (((dataAdapter != null)))
                    dataAdapter.Dispose();
            }

            if ((mustCloseConnection))
                connection.Close();

        }
        #endregion

        #region "UpdateDataset"
        // Executes the respective command for each inserted, updated, or deleted row in the DataSet.
        // e.g.:  
        //   UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order")
        // Parameters:
        // -insertCommand: A valid transact-OleDB statement or stored procedure to insert new records into the data source
        // -deleteCommand: A valid transact-OleDB statement or stored procedure to delete records from the data source
        // -updateCommand: A valid transact-OleDB statement or stored procedure used to update records in the data source
        // -dataSet: the DataSet used to update the data source
        // -tableName: the DataTable used to update the data source

        public static void UpdateDataset(OleDbCommand insertCommand, OleDbCommand deleteCommand, OleDbCommand updateCommand, DataSet dataSet, string tableName)
        {
            if ((insertCommand == null))
                throw new ArgumentNullException("insertCommand");
            if ((deleteCommand == null))
                throw new ArgumentNullException("deleteCommand");
            if ((updateCommand == null))
                throw new ArgumentNullException("updateCommand");
            if ((dataSet == null))
                throw new ArgumentNullException("dataSet");
            if ((tableName == null || tableName.Length == 0))
                throw new ArgumentNullException("tableName");

            // Create a OleDBDataAdapter, and dispose of it after we are done
            OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
            try
            {
                // Set the data adapter commands
                dataAdapter.UpdateCommand = updateCommand;
                dataAdapter.InsertCommand = insertCommand;
                dataAdapter.DeleteCommand = deleteCommand;

                // Update the dataset changes in the data source
                dataAdapter.Update(dataSet, tableName);

                // Commit all the changes made to the DataSet
                dataSet.AcceptChanges();
            }
            finally
            {
                if (((dataAdapter != null)))
                    dataAdapter.Dispose();
            }
        }
        #endregion

    }
    // AccessHelper

    // AccessHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the
    // ability to discover parameters for stored procedures at run-time.
    public sealed class AccessHelperParameterCache
    {

        #region "private methods, variables, and constructors"


        // Since this class provides only static methods, make the default constructor private to prevent 
        // instances from being created with "new AccessHelperParameterCache()".
        private AccessHelperParameterCache()
        {
        }
        // New 


        private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());
        // Deep copy of cached OleDBParameter array
        private static OleDbParameter[] CloneParameters(OleDbParameter[] originalParameters)
        {

            int i = 0;
            int j = originalParameters.Length - 1;
            OleDbParameter[] clonedParameters = new OleDbParameter[j + 1];

            for (i = 0; i <= j; i++)
            {
                clonedParameters[i] = (OleDbParameter)((ICloneable)originalParameters[i]).Clone();
            }

            return clonedParameters;
        }
        // CloneParameters

        #endregion

        #region "caching functions"

        // add parameter array to the cache
        // Parameters
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandText - the stored procedure name or T-OleDB command 
        // -commandParameters - an array of OleDBParamters to be cached 
        public static void CacheParameterSet(string connectionString, string commandText, params OleDbParameter[] commandParameters)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");
            if ((commandText == null || commandText.Length == 0))
                throw new ArgumentNullException("commandText");

            string hashKey = connectionString + ":" + commandText;

            paramCache[hashKey] = commandParameters;
        }
        // CacheParameterSet

        // retrieve a parameter array from the cache
        // Parameters:
        // -connectionString - a valid connection string for a OleDBConnection 
        // -commandText - the stored procedure name or T-OleDB command 
        // Returns: An array of OleDBParamters 
        public static OleDbParameter[] GetCachedParameterSet(string connectionString, string commandText)
        {
            if ((connectionString == null || connectionString.Length == 0))
                throw new ArgumentNullException("connectionString");
            if ((commandText == null || commandText.Length == 0))
                throw new ArgumentNullException("commandText");

            string hashKey = connectionString + ":" + commandText;
            OleDbParameter[] cachedParameters = (OleDbParameter[])paramCache[hashKey];

            if (cachedParameters == null)
            {
                return null;
            }
            else
            {
                return CloneParameters(cachedParameters);
            }
        }
        // GetCachedParameterSet

        #endregion

    }
    // AccessHelperParameterCache 
}